--
-- @Author:      name
-- @DateTime:    2019-11-04 23:05:48
-- @Description: 数据库管理

local skynet = require "skynet"
local cjson = require("cjson")


local MessageHandler = class("MessageHandler")

---------------------------------------------------------
-- Private
---------------------------------------------------------
function MessageHandler:ctor(message_dispatch)
	self.message_dispatch = message_dispatch
	self.mysql = nil
	self.redis = nil
	self:register()
end

function MessageHandler:register()
	self.message_dispatch:registerSelf('start', handler(self, self.start))
	self.message_dispatch:registerSelf('hotfix', handler(self, self.hotfixFile))
end


--热更文件
function MessageHandler:hotfixFile(file_name)
    dbglog("__111__hotfix_____", file_name)
    return global.hotfix:hotfixFile(file_name)
    
end

--redis的hash结果转为正常table
function MessageHandler:redisToTable(res, fields)
	if not res or type(res) ~= "table" then 
		return res
	end
	local data = {}
	if not fields then
		for i=1, #res, 2 do
			data[res[i]] = res[i+1]
		end
	else
		for i=1, #res do
			data[fields[i]] = t[i]
		end
	end
	return data
end

--发送消息给Redis
function MessageHandler:callRedis(cmd, ...)
	if not self.redis then 
		return 
	end
	local res = skynet.call(self.redis, "lua", "redis_cmd", cmd, ...)
	return res
end

function MessageHandler:sendRedis(cmd, ...)
	if not self.redis then 
		return 
	end
	skynet.send(self.redis, "lua", "redis_cmd", cmd, ...)	
end

--发送消息给mongo
function MessageHandler:callMongo(collection, cmd, ...)
	if not self.mongo then 
		return 
	end
	local res = skynet.call(self.mongo, "lua", "mongo_cmd", collection, cmd, ...)
	return res
end

function MessageHandler:sendMongo(collection, cmd, ...)
	if not self.mongo then 
		return 
	end
	skynet.send(self.mongo, "lua", "mongo_cmd", collection, cmd, ...)	
end

--db_id1 用户id列表所在库
--db_id2 要落地数据所在库
--data_prefix 数据前缀
function MessageHandler:landingData(db_id1, db_id2, hash_name, collection, data_prefix)
	self:callRedis("select", db_id1)	
	local base_list = self:callRedis("hgetall", hash_name)
	base_list = self:redisToTable(base_list) or {}
	local res = nil
	self:callRedis("select", db_id2) --切到8号库	
	for uid, nums in pairs(base_list) do 
	
		local user_info = self:callRedis("get", data_prefix..uid)		
		if user_info and string.len(user_info) > 2 then 
			user_info = cjson.decode(user_info)			
			dbglog("_____落地___begin",db_id2, uid)
			res = self:callMongo(collection, "update", {_id=tonumber(uid)}, {['$set']=user_info}, true)			
			dbglog("_____落地___end",db_id2, uid)
		end		

	end

	--删除redis中db_id1库的记录
	self:callRedis("select", db_id1)
	local pop_code = [[
	    local dqk = KEYS[1]	    
	    local uid = ARGV[1]
	    local seq = ARGV[2]	
	    if redis.call('hget',dqk,uid) == seq then
	        return redis.call('hdel',dqk,uid)
	    end
	]]	
	for uid, nums in pairs(base_list) do 
		self:callRedis("eval", pop_code, 1, hash_name, tonumber(uid), tonumber(nums))
	end

end

--检查redis 10号库如果哈希表里有值就落地到mongo
function MessageHandler:checkRedisDb()

	self:landingData(10, 8, "writable_base_queue", "base", "base_" )
	self:landingData(7, 1, "writable_uid_queue", "users", "data_" )

end




----------------------------------------------------------------------
--CMD
----------------------------------------------------------------------
function MessageHandler:start()
	dbglog("__worker______start____")

	--redis操作服务
	self.redis = skynet.newservice("redis_service")
	skynet.call(self.redis, "lua", "start")

	self.mongo = skynet.newservice("mongo_service")
	skynet.call(self.mongo, "lua", "start")


	-- dbglog("__数据库服务启动完成____")

	--定时落地
	skynet.fork(function( ... )
		while true do
			skynet.sleep(100)
			self:checkRedisDb()			
		end
	end)
end






return MessageHandler